#ifndef _CORE_ITCP_H_
#define _CORE_ITCP_H_

#if defined(__cplusplus)
extern "C" {
#endif

#include "../sysdep/core_stdinc.h"
#include "core_string.h"
#include "core_log.h"
#include "core_auth.h"

#include "../aiot_state_api.h"
#include "../aiot_sysdep_api.h"
#include "../aiot_itcp_api.h"

typedef enum {
    CORE_ITCP_SM_READ_HEADER,
    CORE_ITCP_SM_READ_BODY
} core_itcp_sm_t;

typedef struct {
    core_itcp_sm_t sm;
    uint32_t body_total_len;
    uint32_t body_read_len;
} core_itcp_session_t;

typedef struct {
    uint32_t code;
    uint8_t *content;
    uint32_t content_len;
    uint32_t content_total_len;
} core_itcp_response_t;

typedef struct {
    aiot_sysdep_portfile_t *sysdep;
    void *network_handle;
    char *eth;
    char *host;
    uint16_t port;
    char *extend_devinfo;
    uint32_t connect_timeout_ms;
    uint32_t send_timeout_ms;
    uint32_t recv_timeout_ms;
    uint32_t auth_timeout_ms;
    uint32_t deinit_timeout_ms;
    uint32_t header_line_max_len;
    uint32_t body_buffer_max_len;
    aiot_sysdep_network_cred_t *cred;
    char *token;
    uint8_t long_connection;
    uint8_t exec_enabled;
    uint32_t exec_count;
    uint8_t core_exec_enabled;
    uint32_t core_exec_count;
    void *data_mutex;
    void *send_mutex;
    void *recv_mutex;
    core_itcp_session_t session;
    aiot_itcp_event_handler_t event_handler;
    aiot_itcp_recv_handler_t recv_handler;
    aiot_itcp_recv_handler_t core_recv_handler;
    void *userdata;
    void *core_userdata;
} core_itcp_handle_t;

#define CORE_ITCP_MODULE_NAME "ITCP"
#define CORE_ITCP_DEINIT_INTERVAL_MS               (100)

#define CORE_ITCP_DEFAULT_CONNECT_TIMEOUT_MS       (10 * 1000)
#define CORE_ITCP_DEFAULT_AUTH_TIMEOUT_MS          ( 5 * 1000 + 0 * 100 + 0 * 10) /* Auth 超时时间(单位ms) */
#define CORE_ITCP_DEFAULT_SEND_TIMEOUT_MS          ( 5 * 1000 + 0 * 100 + 0 * 10) /* Send 超时时间(单位ms) */
#define CORE_ITCP_DEFAULT_RECV_TIMEOUT_MS          ( 0 * 1000 + 2 * 100 + 0 * 10) /* Recv 超时时间(单位ms) */
#define CORE_ITCP_DEFAULT_HEADER_LINE_MAX_LEN      (32 + 8)
#define CORE_ITCP_DEFAULT_BODY_MAX_LEN             (1024 + 512)
#define CORE_ITCP_DEFAULT_DEINIT_TIMEOUT_MS        (2 * 1000)

typedef enum {
    CORE_ITCPOPT_ETH,                   /* 数据类型: (char *), 网卡名称 */
    CORE_ITCPOPT_HOST,                  /* 数据类型: (char *), 服务器域名 */
    CORE_ITCPOPT_PORT,                  /* 数据类型: (uint16_t), 服务器端口号 */
    CORE_ITCPOPT_NETWORK_CRED,          /* 数据类型: (aiot_sysdep_network_cred_t *), 网络安全凭证, 默认值: NULL */
    CORE_ITCPOPT_CONNECT_TIMEOUT_MS,    /* 数据类型: (uint32_t), 建立网络连接的超时时间 */
    CORE_ITCPOPT_SEND_TIMEOUT_MS,       /* 数据类型: (uint32_t), 网络发送超时时间(单位ms) */
    CORE_ITCPOPT_RECV_TIMEOUT_MS,       /* 数据类型: (uint32_t), 网络接受超时时间(单位ms) */
    CORE_ITCPOPT_DEINIT_TIMEOUT_MS,     /* 数据类型: (uint32_t), 销毁itcp实例时, 等地啊其他api执行完毕的时间 */
    CORE_ITCPOPT_HEADER_LINE_MAX_LEN,   /* 数据类型: (uint32_t), itcp协议中单行header的最大长度 */
    CORE_ITCPOPT_BODY_BUFFER_MAX_LEN,   /* 数据类型: (uint32_t), 每次读取的body最大长度 */
    CORE_ITCPOPT_EVENT_HANDLER,         /* 数据类型: (aiot_itcp_event_handler_t), 用户事件回调函数, 默认值: NULL */
    /* 以上选项配置的数据与 AIOT_ITCPOPT_XXX 共用 */
    CORE_ITCPOPT_USERDATA,              /* 数据类型: (void *), 用户上下文数据指针, 默认值: NULL */
    CORE_ITCPOPT_RECV_HANDLER,          /* 数据类型: (aiot_itcp_event_handler_t), 用户数据接受回调函数, 默认值: NULL */
    CORE_ITCPOPT_MAX
} core_itcp_option_t;

typedef struct {
    char       *method;             /* ITCP请求方法 */
    char       *path;               /* ITCP请求的路径 */
    char       *header;             /* ITCP请求的头部 */
    uint8_t    *content;            /* 指向用户待发送Content的指针 */
    uint32_t    content_len;        /* 用户待发送Content的长度 */
} core_itcp_request_t;

/**
 * @brief 初始化一个ITCP实例, 并返回实例句柄
 *
 * @return void*
 * @retval NotNull core ITCP句柄
 * @retval Null 初始化ITCP实例失败
 */
void *core_itcp_init(void);

/**
 * @brief 设置ITCP实例选项
 *
 * @param[in] handle ITCP句柄
 * @param option 配置选项, 可查看枚举类型 @ref core_itcp_option_t
 * @param[in] data 配置数据, 每个选项对应的数据类型可查看 @ref core_itcp_option_t
 * @return int32_t
 * @retval STATE_SUCCESS, 成功
 * @retval STATE_ITCP_HANDLE_IS_NULL, ITCP句柄为NULL
 * @retval STATE_USER_INPUT_OUT_RANGE, 用户输入参数无效
 * @retval STATE_SYS_DEPEND_MALLOC_FAILED, 内存分配失败
 *
 */
int32_t core_itcp_setopt(void *handle, core_itcp_option_t option, void *data);

/**
 * @brief 建立网络连接
 *
 * @param handle ITCP句柄
 * @return int32_t
 * @retval STATE_SUCCESS 网络连接建立成功
 * @retval <STATE_SUCCESS 网络连接建立失败
 */
int32_t core_itcp_connect(void *handle);

/**
 * @brief 发送ITCP请求
 *
 * @param[in] handle ITCP句柄
 * @param request 请求结构体, 查看 @ref core_itcp_request_t
 * @return int32_t
 * @retval > 0, 已发送的数据长度
 * @retval STATE_ITCP_HANDLE_IS_NULL, ITCP句柄为NULL
 * @retval STATE_USER_INPUT_NULL_POINTER, 用户输入参数为NULL
 * @retval STATE_USER_INPUT_MISSING_HOST, 用户未配置Host
 * @retval STATE_SYS_DEPEND_MALLOC_FAILED, 内存分配失败
 * @retval STATE_SYS_DEPEND_NWK_EST_FAILED, 网络建立连接失败
 * @retval STATE_SYS_DEPEND_NWK_CLOSED, 网络连接已关闭
 * @retval STATE_SYS_DEPEND_NWK_WRITE_LESSDATA, 网络发送超时
 */
int32_t core_itcp_send(void *handle, const core_itcp_request_t *request);

/**
 * @brief 接受ITCP应答数据, 内部将解析状态码和Header并通过回调函数通知用户, 若应答中有body则保存到用户缓冲区中
 *
 * @param[in] handle ITCP句柄
 * @param buffer 指向存放接受
 * @param buffer_len
 * @return int32_t
 * @retval >= 0, 接受到的ITCP body数据长度
 * @retval STATE_ITCP_HANDLE_IS_NULL, ITCP句柄为NULL
 * @retval STATE_USER_INPUT_NULL_POINTER, 用户输入参数为NULL
 * @retval STATE_USER_INPUT_OUT_RANGE, buffer_len为0
 * @retval STATE_SYS_DEPEND_NWK_CLOSED, 网络连接已关闭
 * @retval STATE_SYS_DEPEND_NWK_READ_OVERTIME, 网络接收超时
 * @retval STATE_ITCP_RECV_LINE_TOO_LONG, ITCP单行数据过长, 内部无法解析
 * @retval STATE_ITCP_PARSE_STATUS_LINE_FAILED, 无法解析状态码
 * @retval STATE_ITCP_GET_CONTENT_LEN_FAILED, 获取Content-Length失败
 *
 */
int32_t core_itcp_recv(void *handle);

/**
 * @brief 销毁参数p_handle所指定的ITCP实例
 *
 * @param[in] p_handle 指向ITCP句柄的指针
 * @return int32_t
 * @retval STATE_SUCCESS 成功
 * @retval STATE_USER_INPUT_NULL_POINTER 参数p_handle为NULL或者p_handle指向的句柄为NULL
 */
int32_t core_itcp_deinit(void **p_handle);

#if defined(__cplusplus)
}
#endif

#endif /* #ifndef _CORE_ITCP_H_ */
